﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace ShareB.Models
{
    #region Publication Configuration models
    public class PubConfModel
    {
        //id da configuração
        public int ConfID { get; set; }

        //nome da configuração
        public string ConfName { get; set; }

        //lista de campos que fazem parte da configuração
        public IList<MetaFieldModel> fieldsConf { get; set; }

        public bool Included { get; set; }

        //inicializações necessárias
        public PubConfModel()
        {
            fieldsConf = new List<MetaFieldModel>();
        }

    }

    //model to register a new confiuration for a publication type
    public class NewPubConfModel : PubConfModel
    {
        //lista de campos possiveis a incluir
        public IList<IncludeMetaModel> includedFields { get; set; }


        public NewPubConfModel()
        {
            includedFields = new List<IncludeMetaModel>();
        }
    }
    #endregion


    #region Publication models
    public class PublicationModel
    {
        //the id of this Publication
        public int PublicationID { get; set; }
        //the id of the author of the message
        public int UserID { get; set; }
        //the username of the author of the message
        public string Username { get; set; }
        //the id of this publication configuration
        public int PubConfID { get; set; }
        //creation date
        public DateTime StartDate { get; set; }
        //last edited date
        public DateTime EditDate { get; set; }
        //Tittle
        public string Tittle { get; set; }
        //List of fields on this publication
        public IList<FieldModel> Fields { get; set; }

        //needed inicializations
        public PublicationModel()
        {
            Fields = new List<FieldModel>();
        }
    }

    public class NewPublicationModel : PublicationModel
    {
        public PubConfModel configuration { get; set; }

        public NewPublicationModel()
        {
            configuration = new PubConfModel();
        }
    }

    //compact information to be displayed in a users profile and suport the users message management
    public class MessageModel
    {
        //the id of the publication the message refers to
        public int PublicationID { get; set; }
        //the author of the message
        public int UserID { get; set; }
        //wheter this message has been read or not
        public bool Unread { get; set; }

        //incluir a publication talvez ou vai-se buscar depois pelo ID. por pensar melhor
    }

    //Model to implement a kind of a users Inbox messages
    public class MessagesModel
    {
        //List of messages
        List<MessageModel> Messages { get; set; }

        //number of unread messages
        public int NrUnread { get; set; }

    }

    #endregion

    public class PubConfService
    {
        ShareBDataContext db = new ShareBDataContext();

        //Get Configurations by ID + Metafields
        public PubConfModel GetConfigurations(int pubID)
        {
            PubConfModel model = new PubConfModel();
            //fetch metafields in the database
            foreach (PublicationConfiguration conf in db.PublicationConfigurations)
            {
                
                if (conf.PubConfID == pubID)
                {
                    model.ConfID = conf.PubConfID;
                    model.ConfName = conf.ConfigurationName;
                    model.fieldsConf = GetMetaFields(conf.PubConfID);
                }
            }

            return model;
        }

        
        //Get Existing Metafields
        public IList<PubConfModel> GetAllConfigurations()
        {
            IList<PubConfModel> confList = new List<PubConfModel>();

            //fetch metafields in the database
            foreach (PublicationConfiguration conf in db.PublicationConfigurations)
            {
                confList.Add(new PubConfModel
                {
                    ConfID = conf.PubConfID,
                    ConfName = conf.ConfigurationName,
                    fieldsConf = GetMetaFields(conf.PubConfID)
                });
            }
            return confList;
        }

        public IList<MetaFieldModel> GetMetaFields(int configurationID)
        {
            IList<MetaFieldModel> metaList = new List<MetaFieldModel>();

            //fetch metafields in the database
            foreach (PubConfField pub in db.PubConfFields)
            {
                if (pub.PubConfID == configurationID)
                {
                    MetaField meta = db.MetaFields.Single(m => m.MetaFieldID == pub.MetaFieldID);
                    metaList.Add(new MetaFieldModel
                    {
                        FieldName = meta.FieldName,
                        FieldType = meta.FieldType,
                        MetaFieldID = meta.MetaFieldID,
                        Locked = meta.Locked
                    });
                }
            }
            return metaList;
        }

        //add new Publication configuration
        public void CreateConf(PubConfModel model)
        {
            //cria a configuraçao e submete-la na bd
            PublicationConfiguration pf = new PublicationConfiguration
            {
                ConfigurationName = model.ConfName
            };

            db.PublicationConfigurations.InsertOnSubmit(pf);

            //for each metafield in the model, create and submit relation in PubConfFields table
            foreach (MetaFieldModel m in model.fieldsConf)
            {
                PubConfField pub = new PubConfField
                {
                    PubConfID = model.ConfID,
                    MetaFieldID = m.MetaFieldID,
                    Locked = m.Locked
                };
                db.PubConfFields.InsertOnSubmit(pub);
            }

            //save all changes
            db.SubmitChanges();
        }
        /*
        public MetaFieldModel GetMeta(int id)
        {
            //procurar na bd
            MetaField m = db.MetaFields.Single(meta => meta.MetaFieldID == id);

            if (m != null)
                return new MetaFieldModel
                {
                    FieldName = m.FieldName,
                    FieldType = m.FieldType,
                    MetaFieldID = m.MetaFieldID,
                    Locked = m.Locked
                };
            else return null;
        }

        internal void UpdateMeta(MetaFieldModel model)
        {
            MetaField m = db.MetaFields.Single(meta => meta.MetaFieldID == model.MetaFieldID);
            m.FieldName = model.FieldName;
            m.FieldType = model.FieldType;
            m.Locked = model.Locked;

            db.SubmitChanges();
        }*/
    }

    #region services

    public class PublicationService
    {
        ShareBDataContext db;

        public PublicationService()
        {
            db = new ShareBDataContext();
        }

        public IList<FieldModel> GetFields(int publicationID)
        {
            IList<FieldModel> fieldList = new List<FieldModel>();

            //fetch metafields in the database
            foreach (Field fil in db.Fields)
            {
                if (fil.PublicationID == publicationID)
                {
                    Field field = db.Fields.Single(m => m.FieldID == fil.FieldID);
                    fieldList.Add(new FieldModel
                    {
                        FieldName = field.FieldName,
                        FieldID = fil.FieldID,
                        MetaFieldID = field.MetaFieldID,
                        FieldValue = fil.FieldValue,
                        PublicationID = fil.PublicationID
                    });
                }
            }
            return fieldList;
        }

        //Implements View Details Publication
        public IList<PublicationModel> GetAllMyPublication()
        {
            IList<PublicationModel> pubList = new List<PublicationModel>();

            //fetch metafields in the database
            foreach (Publication pub in db.Publications)
            {
                pubList.Add(new PublicationModel
                {
                    UserID = pub.UserID,
                    Tittle = pub.Tittle,
                    PublicationID = pub.PublicationID,
                    PubConfID = pub.PubConfID,
                    Fields = GetFields(pub.PublicationID)
                });
            }
            return pubList;

        }

        public void CreatePublication(PublicationModel model, int pubconfID)
        {
            //PubConfModel pubconf = new PubConfModel();
            //PubConfService pubconfservice = new PubConfService();
            //pubconf = pubconfservice.GetConfigurations(pubconfID);
            
            // GRAVAR A PUBLICACAO
            Publication pub = new Publication
                    {
                        UserID = model.UserID,
                        PubConfID = model.PubConfID,
                        TimeStamp = model.StartDate,
                        Tittle =  model.Tittle                    
                    };

            db.Publications.InsertOnSubmit(pub);
            db.SubmitChanges();

            // GRAVAR CAMPOS NO FIELD, INCREMENTALMENTE
            

            foreach (FieldModel cmodel in model.Fields)
            {
                Field field = new Field
                    {
                        PublicationID = db.Publications.Single(c => c.Tittle == pub.Tittle).PublicationID,
                        MetaFieldID = cmodel.MetaFieldID,
                        FieldName = cmodel.FieldName,
                        FieldValue = cmodel.FieldValue
                    };

                db.Fields.InsertOnSubmit(field);
                db.SubmitChanges();
            }

            
            
        }

    }
    #endregion

}